// system.h 
//	All global variables used in Nachos are defined here.
//
// Copyright (c) 1992-1993 The Regents of the University of California.
// All rights reserved.  See copyright.h for copyright notice and limitation 
// of liability and disclaimer of warranty provisions.

#ifndef SYSTEM_H
#define SYSTEM_H

#include "copyright.h"
#include "utility.h"
#include "thread.h"
#include "scheduler.h"
#include "interrupt.h"
#include "stats.h"
#include "timer.h"
// Provide Mutual Exclusion for lockTable of KernelLocks
#include "synch.h"
// For numphyspages def
#include "machine.h"
#include "../userprog/mmu.h"

// max amount of locks in the system
#define MAX_LOCKS 70
// max amount of conditions in the system
#define MAX_CONDITIONS 70
// max processes
#define MAX_PROCESSES 10
// max number of threads for a user process
#define MaxUserThreads 50
#define CODE 0
#define DATA 1

#define NONE 0
#define EXECUTABLE 1
#define SWAPFILE 2
#define SwapfileSize 40000

// Initialization and cleanup routines
extern void Initialize(int argc, char **argv); 	// Initialization,
						// called before anything else
extern void Cleanup();				// Cleanup, called when
						// Nachos is done.

extern Thread *currentThread;			// the thread holding the CPU
extern Thread *threadToBeDestroyed;  		// the thread that just finished
extern Scheduler *scheduler;			// the ready list
extern Interrupt *interrupt;			// interrupt status
extern Statistics *stats;			// performance metrics
extern Timer *timer;				// the hardware alarm clock


#ifdef USER_PROGRAM
#include "machine.h"

extern Machine* machine;	// user program memory and registers
extern MMU* mmu;
extern OpenFile* swapfile;
extern char* ZeroPage;

/* Data for creating kernel locks */
typedef struct
{
	// the actual lock
	Lock* lock;
	// to find addrspace of thread
	AddrSpace* space;
	bool isDeleted;
	bool isToBeDeleted;
} KernelLock;

/* Data for creating Kernel CVs */
typedef struct
{
		// the actual condition
		Condition* condition;
		AddrSpace* space;
		bool isDeleted;
		bool isToBeDeleted;
} KernelCondition;

extern int amtOfLocks;
extern KernelLock* kernelLockTable[MAX_LOCKS];
extern Lock* kernelLockTableLock;


extern int amtOfCVs;
extern KernelCondition* kernelConditionTable[MAX_CONDITIONS];
extern Lock* kernelConditionTableLock;

// for bitmap object to find memory
extern BitMap* globalPhysicalMemoryBitMap;
extern Lock* memoryBitMapLock;

/* Process table */
typedef struct
{
	Thread* threads[MaxUserThreads];
	int nextThreadLocation;
	int currentThreadCount;
	int activeThreadCount;
	AddrSpace* addrSpace;
	bool isDeleted;
} ProcessTag;

extern ProcessTag* processTable[MAX_PROCESSES]; 
extern Lock* processTableLock;

extern int nextProcessId;
extern int currentProcessesRunning;

extern int currentTLB;
extern Lock* iptLock;

extern BitMap* swapfileBitMap;
extern Lock* swapBitMapLock;

extern Lock* threadIdLock;
extern int nextThreadId;
#endif

#ifdef FILESYS_NEEDED 		// FILESYS or FILESYS_STUB 
#include "filesys.h"
extern FileSystem  *fileSystem;
#endif

#ifdef FILESYS
#include "synchdisk.h"
extern SynchDisk   *synchDisk;
#endif

#ifdef NETWORK
#include "post.h"
extern PostOffice* postOffice;
#endif

#endif // SYSTEM_H
